﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GraphicsFramework.Property;
using GraphicsFramework.Entity;

namespace GraphicsFramework.Drawing.Grid
{
    /// <summary>
    /// This is design for 2D view only (GDI, WPF, and Silverlight).
    /// This is not design for OpenGL and DirectX.
    /// </summary>
    public class FullGrid : BaseGrid
    {

        private DrawProperty minorproperty;
        private DrawProperty majorproperty;
        private DrawProperty centerproperty;

        private bool showmajor;
        private bool showminor;
        private bool showcenter;

        private int width;
        private int height;

        public FullGrid()
            : base(Enum.EnumDrawingType.NONE, Enum.EnumGridType.FULLGRID, "Full Grid", Enum.EnumMouseClicks.NONE)
        {
            minorproperty = new DrawProperty(null, new ColorProperty(255, 230, 230, 230), 1, false);
            majorproperty = new DrawProperty(null, new ColorProperty(255, 200, 200, 200), 1, false);
            centerproperty = new DrawProperty(null, new ColorProperty(255, 125, 125, 125), 1, false);

            showmajor = true;
            showminor = true;
            showcenter = true;
        }

        private void drawHorizontal(GraphicsFramework graphics, DrawProperty property, int size, float division = 1, bool major = true)
        {
            //To control the loop
            bool loop = true;

            float top = graphics.ToCoordY(((int)graphics.Middle.Y) * graphics.GridValue.Y); ;
            float bottom = top;

            float inc = (float)size / (float)division;

            if (major)
            {
                do
                {
                    //From middle to bottom
                    graphics.BasicLine(property, new Point2I(0, (int)top), new Point2I(width, (int)top));

                    //Next Bottom
                    bottom -= inc;

                    //From middle to top
                    if (bottom > 0)
                    {
                        graphics.BasicLine(property, new Point2I(0, (int)bottom), new Point2I(width, (int)bottom));
                    }

                    //Next Top
                    top += inc;

                    //Check of need to exit
                    if (top > height && bottom < 0)
                    {
                        loop = false;
                    }

                } while (loop);
            }
            else
            {
                int counter = 1;

                do
                {
                    if ((counter > 0) && (counter < division))
                    {
                        bottom -= inc;
                        top += inc;

                        //From middle to bottom
                        graphics.BasicLine(property, new Point2I(0, (int)top), new Point2I(width, (int)top));


                        //From middle to top
                        if (bottom > 0)
                        {
                            graphics.BasicLine(property, new Point2I(0, (int)bottom), new Point2I(width, (int)bottom));
                        }

                        //Check of need to exit
                        if (top > height && bottom < 0)
                        {
                            loop = false;
                        }

                        counter++;
                    }
                    else
                    {
                        if (counter == division)
                        {
                            counter = 1;
                            bottom -= inc;
                            top += inc;
                        }
                        else
                        {
                            counter++;
                        }
                    }

                } while (loop);
            }
        }

        private void drawVertical(GraphicsFramework graphics, DrawProperty property, int size, float division = 1, bool major = true)
        {
            //To control the loop
            bool loop = true;

            //
            float right = graphics.ToCoordX(((int)graphics.Middle.X) * graphics.GridValue.X); ;
            float left = right;

            float inc = (float)size / (float)division;

            if (major)
            {
                do
                {
                    //From middle to right
                    graphics.BasicLine(property, new Point2I((int)right, 0), new Point2I((int)right, height));

                    //Next Left
                    left -= inc;

                    //From middle to left
                    if (left > 0)
                    {
                        graphics.BasicLine(property, new Point2I((int)left, 0), new Point2I((int)left, height));
                    }

                    //Next Right
                    right += inc;

                    //Check if need to exit
                    if (right > width && left < 0)
                    {
                        loop = false;
                    }

                } while (loop);
            }
            else
            {
                int counter = 0;

                do
                {
                    if ((counter > 0) && (counter < division))
                    {
                        left -= inc;
                        right += inc;

                        //From middle to right
                        graphics.BasicLine(property, new Point2I((int)right, 0), new Point2I((int)right, height));

                        //From middle to left
                        if (left > 0)
                        {
                            graphics.BasicLine(property, new Point2I((int)left, 0), new Point2I((int)left, height));
                        }

                        //Check if need to exit
                        if (right > width && left < 0)
                        {
                            loop = false;
                        }

                        counter++;
                    }
                    else
                    {
                        if (counter == division)
                        {
                            counter = 1;
                            left -= inc;
                            right += inc;
                        }
                        else
                        {
                            counter++;
                        }
                    }

                } while (loop);
            }
        }

        private void drawCenter(GraphicsFramework graphics)
        {
            //Horizontal Line
            int y = graphics.ToCoordY(0);
            graphics.BasicLine(centerproperty, new Point2I(0, y), new Point2I(width, y));

            //Vertical Line
            int x = graphics.ToCoordX(0);
            graphics.BasicLine(centerproperty, new Point2I(x, 0), new Point2I(x, height));
        }

        public override GraphicBase Clone()
        {
            return null;
        }

        public override void OnRender(GraphicsFramework graphics)
        {
            //If grid line is hidden then exit
            if (!Visible) return;

            int gridsize = graphics.Gridsize;
            float multiplier = graphics.GridMultiplier;
            float multiplier10 = multiplier * 10;

            width = graphics.Width;
            height = graphics.Height;


            if (showminor)
            {
                drawHorizontal(graphics, minorproperty, gridsize, multiplier10, false);
                drawVertical(graphics, minorproperty, gridsize, multiplier10, false);
            }

            if (showmajor)
            {
                drawHorizontal(graphics, majorproperty, gridsize, multiplier);
                drawVertical(graphics, majorproperty, gridsize, multiplier);
            }

            if (showcenter)
            {
                drawCenter(graphics);
            }
        }
    }
}
